﻿Imports System.Drawing.Imaging
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
''' <summary>
''' Texte die momentan auf dem Bildschirm zu lesen sind
''' </summary>
''' <remarks></remarks>
Public Class ObjektText

    Public Text() As String = {}
    Dim ZuSchreibenderText() As String = {}
    Public XStart As Integer
    Public YStart As Integer
    ''' <summary>
    ''' Direct3D Font Objekt
    ''' </summary>
    ''' <remarks></remarks>
    Dim Farben() As Color = {}
    Public Function GetFarben() As Color()
        Return Farben
    End Function
    Dim Schriftgroesse As Integer
    Dim Schreiben As Boolean = False
    Dim Zeile As Integer = 0
    Dim Textstelle As Integer = 0
    Dim TextAbstand As Integer = 0
    Dim Textart As Integer
    Public Function GetSchriftart() As Direct3D.Font
        Return Schriftengine.Fonts(Textart).GetFont
    End Function
    Public Function GetFontDimension(ByVal Zeile As Integer) As Rectangle
        If Zeile < Text.Length Then
            Return GetSchriftart.MeasureString(Schriftengine.MeasureSprite, Text(Zeile), DrawTextFormat.None, Color.Black)
        Else
            Return New Rectangle(0, 0, 0, 0)
        End If
    End Function
    Public Sub New(ByVal neuText() As String, ByVal X As Integer, ByVal Y As Integer, ByVal neueFarben() As Color, ByVal neueSchriftart As Schriftengine.Schriftarten, ByVal neuSchriftgroesse As Integer, ByVal Stil As System.Drawing.FontStyle, Optional ByVal neuSchreiben As Boolean = False, Optional ByVal neuTextAbstand As Integer = 3)
        Textart = Schriftengine.CreateSchriftart(neueSchriftart, neuSchriftgroesse, Stil)
        neuerText(neuText, X, Y, neueFarben, neuSchreiben)
        TextAbstand = neuTextAbstand
    End Sub
    Public Sub neuerText(ByVal neuerText() As String, ByVal StartX As Integer, ByVal StartY As Integer, ByVal Textfarben() As Color, Optional ByVal neuSchreiben As Boolean = False, Optional ByVal neuerTextabstand As Integer = 3)
        TextAbstand = neuerTextabstand
        XStart = StartX
        YStart = StartY
        Farben = Textfarben
        Schreiben = neuSchreiben
        If Schreiben = False Then
            Text = neuerText
        Else
            ZuSchreibenderText = neuerText
        End If
    End Sub
    Public Sub neuerText(ByVal neuerText() As String, ByVal Textfarben() As Color, Optional ByVal neuSchreiben As Boolean = False, Optional ByVal neuerTextabstand As Integer = 3)
        TextAbstand = neuerTextabstand
        Farben = Textfarben
        Schreiben = neuSchreiben
        If Schreiben = False Then
            Text = neuerText
        Else
            ZuSchreibenderText = neuerText
        End If
    End Sub
    Public Function Malen(ByVal Pos As Point) As Boolean
        If Schreiben = True Then
            If Text.Length = 0 Then Array.Resize(Text, 1)
            Textstelle += 1
            Dim Zeilemom As String = ZuSchreibenderText(Zeile)
            If Textstelle >= Zeilemom.Count Then
                Text(Zeile) = ZuSchreibenderText(Zeile)
                Textstelle = 0
                Zeile += 1
                If Zeile >= ZuSchreibenderText.Length Then
                Else
                    Array.Resize(Text, Text.Length + 1)
                End If
            Else
                If ZuSchreibenderText(Zeile) = "" Then
                    Text(Zeile) = " "
                Else
                    Text(Zeile) = ZuSchreibenderText(Zeile).Remove(Textstelle)
                End If
            End If
        End If
        Dim Hoehe As Integer
        Dim Mat As Matrix = Matrix.Identity
        Mat.M41 = Pos.X
        Mat.M42 = Pos.Y
        Grafikengine.Sprite.Transform = Mat
        If Text.Length > 0 Then
            Hoehe = Schriftengine.Fonts(Textart).GetFont.MeasureString(Grafikengine.Sprite, Text(0), DrawTextFormat.None, Color.Black).Height
        End If
        For I = 0 To Text.Length - 1
            Dim Farbe As Color = Color.Black
            If IsNothing(Farben) = False Then
                If Farben.Length = 1 Then
                    Farbe = Farben(0)
                Else
                    Farbe = Farben(I)
                End If
            End If

            Schriftengine.Fonts(Textart).GetFont.DrawText(Grafikengine.Sprite, Text(I), XStart, YStart + I * (Hoehe + TextAbstand), Farbe)

        Next
        If Zeile >= ZuSchreibenderText.Length Or Schreiben = False Then
            Zeile = 0
            Schreiben = False
            Return False
        End If
        Return True
    End Function
    Public Sub FertigGeschrieben()
        Schreiben = False
        Text = ZuSchreibenderText
    End Sub
    Public Function IsGeschrieben() As Boolean
        Return Not Schreiben
    End Function
    Public Shared Function getStringsZeilenweise(ByVal S() As String, ByVal Schriftart As Font, ByVal TextBreite As Integer) As String()
        Dim L As New List(Of String)
        For I = 0 To S.Length - 1
            Dim D() As String = getStringsZeilenweise(S(I), Schriftart, TextBreite)
            For I2 = 0 To D.Length - 1
                L.Add(D(I2))
            Next
        Next
        Return L.ToArray
    End Function
    Public Shared Function getStringsZeilenweise(ByVal Text As String, ByVal Schriftart As Font, ByVal TextBreite As Integer) As String()
        If Text.Contains(Environment.NewLine) Then
            Dim Txte() As String = Text.Split(Environment.NewLine)
            Dim ZeilenZusammen() As String = {}
            For i = 1 To Txte.Length - 1
                Txte(i) = Txte(i).Remove(0, 1)
            Next
            For Each Txt In Txte
                For Each Line In getStringsZeilenweise(Txt, Schriftart, TextBreite)
                    Array.Resize(ZeilenZusammen, ZeilenZusammen.Length + 1)
                    ZeilenZusammen(ZeilenZusammen.Length - 1) = Line
                Next
            Next
            Return ZeilenZusammen
        End If
        If Text.Length <= 0 Then Return New String() {Text}
        Dim TextTeile() As String = Text.Split(" ")
        Dim Zeilen() As String = {""}
        Dim WortIndAnfang As Integer = 0
        Dim WortIndEnde As Integer = 0
        While WortIndAnfang < TextTeile.Length
            WortIndEnde = WortIndAnfang
            Dim s As String = ""
            If getWoerterBreite(TextTeile, WortIndAnfang, WortIndEnde, Schriftart) <= TextBreite Then
                'zumindest ein Wort ist OK 
                'mal schauen, wie weit wir es treiben koennen 
                Do While getWoerterBreite(TextTeile, WortIndAnfang, WortIndEnde, Schriftart) <= TextBreite
                    WortIndEnde += 1
                    If WortIndEnde > TextTeile.Length - 1 Then
                        'ups, das war vielleicht ein bischen viel.
                        Exit Do
                    End If
                Loop
                WortIndEnde -= 1 'das war wohl eins zu viel 

                If WortIndEnde > WortIndAnfang Then
                    For i2 = WortIndAnfang To WortIndEnde - 1
                        s += TextTeile(i2) + " "
                    Next
                    s += TextTeile(WortIndEnde)   'NICHT ANFANG
                Else
                    s = TextTeile(WortIndAnfang)
                End If

                Zeilen(Zeilen.Length - 1) = s
                Array.Resize(Zeilen, Zeilen.Length + 1)
            Else
                'Wenn nichtmal ein Wort geht, muessen wir halt das doch aufteilen, da ich aber keine silbentrennung machen will (das dauert glaub ich doch zu lange)(zum coden ) werden einfach die buchstaben abgetrennt, die zuviel sind!
                'na dann eben das ganze Char fuer Char
                'aber am besten rueckwaerts, da ja vermutlich dieser Fall eher fuer lange Woerter zutrifft, und die schneidet wan vermutlich besser ab!
                Dim RestWort As String = TextTeile(WortIndAnfang)
                While RestWort.Length > 0
                    Dim Wort As String = RestWort
                    Do While getTextBreite(Wort, Schriftart) > TextBreite
                        'Das Wort ist immer noch zu gross
                        Wort = Wort.Remove(Wort.Length - 1)
                        If Wort.Length <= 1 Then
                            'Oha! Jetzt ist wirklich nicht mehr viel von dem Wort uebrig!
                            'Was machen wir jetzt mit dem einen Buchstaben?
                            'am besten einfach trotzdem reinschreiben.
                            Exit Do
                        End If
                    Loop
                    Zeilen(Zeilen.Length - 1) = Wort
                    Array.Resize(Zeilen, Zeilen.Length + 1)
                    RestWort.Remove(0, Wort.Length)
                End While
            End If

            WortIndAnfang = WortIndEnde + 1
        End While
        Array.Resize(Zeilen, Zeilen.Length - 1) 'eine ist ja zuviel
        Return Zeilen
    End Function
    Private Shared Function getWoerterBreite(ByVal Woerter() As String, ByVal WortIndAnfang As Integer, ByVal WortIndEnde As Integer, ByVal Schriftart As Font) As Integer
        Dim s As String = ""
        If WortIndEnde > WortIndAnfang Then
            For i = WortIndAnfang To WortIndEnde - 1
                s += Woerter(i) + " "
            Next
            s += Woerter(WortIndEnde)
        Else
            s = Woerter(WortIndAnfang)
        End If
        Return getTextBreite(s, Schriftart)
    End Function
    Private Shared Function getTextBreite(ByVal Text As String, ByVal Schriftart As Font) As Integer
        Dim ret As Integer
        Schriftengine.MeasureSpriteLocker.Lock()
        ret = Schriftart.MeasureString(Schriftengine.MeasureSprite, Text, DrawTextFormat.None, Color.Blue).Width()
        Schriftengine.MeasureSpriteLocker.Unlock()
        Return ret
    End Function
End Class
